        /* 在这里的是成吨的小技巧，包括
         * TargetMethods，CodeMatcher（针对LearnFactory）
         * 针对迭代器的postfix（仅教程）
         * Transpiler调用函数
         */
        // TargetMethods，CodeMatcher（针对LearnFactory）
        [HarmonyPatch]
        public static class All_EndTick {// used for 2  FactorySystem functions.
            static IEnumerable<MethodBase> TargetMethods()
            {
                Type[] t=typeof(Building).Assembly.GetTypes();
                foreach(Type ty in t){
                    MethodInfo[] m=ty.GetMethods();
                    foreach(MethodInfo i in m)if(i.Name=="EndTick"){
#if DEBUG
            logger("LearnFactory-注入类别"+ty.ToString()+"的EndTick方法");
#endif
                        yield return i;
                    }
                }
            }
            static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) {
                //return instructions;
                return new CodeMatcher(instructions)
                    .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                        new CodeMatch(OpCodes.Ldarg_0),
                        new CodeMatch(i=> i.opcode==OpCodes.Ldfld && ((FieldInfo)i.operand).Name == "Time"), // match method 2
                        new CodeMatch(OpCodes.Ldc_I4_1),
                        new CodeMatch(OpCodes.Add)
                    ).Repeat( matcher => // Do the following for each match
                        matcher
                        .Advance(2) // Move cursor to after ldfld
                        .SetAndAdvance(
                            OpCodes.Ldc_I4,speed_mul
                        )
                    ).InstructionEnumeration();
            }
        }
        //针对迭代器的postfix（仅教程）
        public class OriginalCode
        {
            public string GetName()
            {
                return "David";
            }

            public IEnumerable<int> GetNumbers()
            {
                yield return 1;
                yield return 2;
                yield return 3;
            }
        }

        [HarmonyPatch(typeof(OriginalCode), nameof(OriginalCode.GetName))]
        class Patch1
        {
            static string Postfix(string name)
            {
                return "Hello " + name;
            }
        }

        [HarmonyPatch(typeof(OriginalCode), nameof(OriginalCode.GetNumbers))]
        class Patch2
        {
            static IEnumerable<int> Postfix(IEnumerable<int> values)
            {
                yield return 0;
                foreach (var value in values)
                    if (value > 1)
                        yield return value * 10;
                yield return 99;
            }
        }
        // Transpiler调用函数
        [HarmonyDebug]
        [HarmonyPatch(typeof(MakeSystem), "StartChangeItem")]
        public static class MakeSystemStartChangeItem {
            static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions){ // 通过ThirdItemId的读写修改进行注入
                logger("   ->搜索ThirdItemId");
                uint flag=0xDEADBEFF;
                foreach (var instruction in instructions) { // 理论上只有before和hit节需要处理
                    if(flag==0xDEADBEFF && instruction.opcode==OpCodes.Ldc_I4_0){ // before
                        yield return instruction;
                        flag=0xDEADCAFE;
                    } else if(flag==0xDEADCAFE){
                        // instruction.opcode==OpCodes.Callvirt && (MethodInfo)instruction.operand == typeof(what_you_want).GetMethod("to_call")
                        // instruction.opcode==OpCodes.Ldfld && ((FieldInfo)instruction.operand).Name == "name"
                        if(instruction.opcode==OpCodes.Callvirt && (MethodInfo)instruction.operand == typeof(MakeSystem).GetMethod("GetChangeVaule")){ // hit
                            logger("[II]:找到int changeVaule = this.GetChangeVaule(i, 0);.");
                            // now stack is [this i 0]
                            yield return new CodeInstruction(OpCodes.Call,typeof(MakeSystemStartChangeItem).GetMethod("Craft"));
                            // instruction should return int(=0) for skipping further instructions
                            flag=0;
                        }else{ // miss
                            yield return instruction;
                            flag=0xDEADBEFF;
                        }
                    } else { // after
                        yield return instruction;
                    }
                }
                if(flag!=0)logger("[EE]:注入失败，请检查源码是否发生了改变")
            }
            public static int Craft(MakeSystem makeSystem,int i,int zero){
                foreach(int[3] i in add3){
                    DateFile.instance.ChangItemDate(makeSystem.secondItemId, i[1], 8*i[2], false);
                }
                return 0;
            }
        }
